Kinase inhibitors over a dose range#
pki() serves cpg0008-pki from the Cell Painting Gallery [Weisbart et al., 2024], a collaboration between the Broad Institute and the Gray lab that profiles selective protein kinase inhibitors. Fifteen kinase inhibitors were run over a seven-point dose range, eleven of them at three doses and four at a single dose, across eight plates in four cell lines, two plates each: PATU-8988T, MDA-MB-231, U2OS and A549. Every plate carries the same plate map, so a treatment’s 32 to 64 replicate wells span all four lines, 8 to 16 in each. Metadata_CellLine records the line of each well. The object is well-level.
The four lines differ biologically, so a treatment’s wells in two lines are not interchangeable replicates. Subset or group by Metadata_CellLine before counting replicates or scoring reproducibility. The tutorials that use pki pool the four lines, and say so where it matters.
The design spends wells on replicates rather than on a full concentration ladder, so it is the workhorse compound screen here for hit calling and normalization, not for curve fitting. For a screen laid out the other way, many concentrations per compound for fitting a concentration-response curve, see OASIS pilot.
Use it if your own data is a compound screen with many replicate wells per treatment and you want to call hits, normalize against controls or check for plate artifacts. Hits, effects and cell loss, Normalize, select, aggregate and Plate artifacts and corrections all run on it.
import pandas as pd
import mantispy as mt
adata = mt.ds.pki()
adata
AnnData object with n_obs × n_vars = 3072 × 5839
obs: 'Metadata_plate_map_name', 'Metadata_broad_sample', 'Metadata_mg_per_ml', 'Metadata_mmoles_per_liter', 'Metadata_solvent', 'Metadata_Plate', 'Metadata_Well', 'Metadata_Site_Count', 'Metadata_Count_Cells', 'Metadata_Count_CellsIncludingEdges', 'Metadata_Count_Cytoplasm', 'Metadata_Count_Nuclei', 'Metadata_Count_NucleiIncludingEdges', 'Metadata_Object_Count', 'Metadata_Barcode', 'Metadata_Supplier', 'Metadata_Supplier_Catalog', 'Metadata_pert_type', 'Metadata_control_type', 'Metadata_Row', 'Metadata_Col', 'Metadata_CellCount', 'Metadata_SiteCount', 'Metadata_Control_Type', 'Metadata_Control', 'Metadata_Compound', 'Metadata_Concentration', 'Metadata_ConcentrationUnit', 'Metadata_MOA', 'Metadata_Perturbation', 'Metadata_Perturbation_Type', 'Metadata_CellLine'
var: 'object', 'feature_group', 'feature', 'channel', 'scale', 'angle', 'gray_levels', 'radial_bin', 'params', 'is_feature', 'feature_kind'
uns: 'mantispy'
layers: None (.X)
pd.crosstab(adata.obs["Metadata_Plate"], adata.obs["Metadata_CellLine"])
| Metadata_CellLine | A549 | MDA-MB-231 | PATU-8988T | U2OS |
|---|---|---|---|---|
| Metadata_Plate | ||||
| BR00122970 | 0 | 0 | 384 | 0 |
| BR00122971 | 0 | 0 | 384 | 0 |
| BR00122972 | 0 | 384 | 0 | 0 |
| BR00122973 | 0 | 384 | 0 | 0 |
| BR00122974 | 0 | 0 | 0 | 384 |
| BR00122975 | 0 | 0 | 0 | 384 |
| BR00122977 | 384 | 0 | 0 | 0 |
| BR00122978 | 384 | 0 | 0 | 0 |
The dose design#
Metadata_Compound names the compound and Metadata_Concentration is the platemap’s mmoles_per_liter (millimolar). The values reach 2 mM, high for a final in-well dose, so this is most likely the source concentration; the final dose is not recorded upstream. Counting wells per compound and dose shows the ladder each treatment was run on. Metadata_Control_Type is negcon for the DMSO wells and poscon for the four positive-control compounds, and Metadata_Control is True for both (schema 2.0). Normalize with reference="negcon", and select the non-DMSO wells with Metadata_Control_Type != "negcon".
obs = adata.obs
design = pd.crosstab(obs["Metadata_Compound"], obs["Metadata_Concentration"])
design.iloc[:8]
| Metadata_Concentration | 0.004 | 0.010 | 0.040 | 0.200 | 0.400 | 1.000 | 2.000 |
|---|---|---|---|---|---|---|---|
| Metadata_Compound | |||||||
| BRD-K15179513-001-03-4 | 0 | 0 | 0 | 0 | 0 | 0 | 32 |
| BRD-K15819326-001-01-6 | 0 | 0 | 0 | 0 | 0 | 0 | 32 |
| BRD-K40109029-001-06-9 | 0 | 0 | 0 | 0 | 0 | 0 | 32 |
| BRD-K95785537-001-26-9 | 0 | 0 | 0 | 0 | 0 | 0 | 32 |
| BRD-U00086672-001-01-9 | 0 | 0 | 0 | 64 | 64 | 64 | 0 |
| BRD-U00086673-001-01-9 | 0 | 0 | 0 | 64 | 64 | 64 | 0 |
| BRD-U00086674-001-01-9 | 0 | 0 | 64 | 64 | 64 | 0 | 0 |
| BRD-U00086675-001-01-9 | 0 | 0 | 64 | 64 | 64 | 0 | 0 |
Cells thin out as the dose rises#
Reading cells per well against concentration already shows the cytotoxic arm of the dose response, before any profile distance is computed: the highest doses leave fewer cells than DMSO.
mt.pl.cell_counts(adata, groupby="Metadata_Concentration")