Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Maps query single-cell data to reference atlases using scArches transfer learning with scVI and scANVI models. Transfers cell type labels without retraining on combined data. Use when annotating new single-cell datasets using pre-trained reference models.
.claude/skills/bio-machine-learning-atlas-mapping/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 214% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 19% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -1% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 105% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 56% | 0% |
<!--
#
#
-->
pythonimport scvi import scanpy as sc # Load pre-trained reference model adata_ref = sc.read_h5ad('reference.h5ad') # Model must have been saved with save_anndata=True scvi.model.SCVI.setup_anndata(adata_ref, layer='counts', batch_key='batch') ref_model = scvi.model.SCVI.load('reference_model/', adata=adata_ref) # Prepare query data adata_query = sc.read_h5ad('query.h5ad') # Subset to reference genes adata_query = adata_query[:, adata_ref.var_names].copy() # Set up query AnnData using reference setup scvi.model.SCVI.prepare_query_anndata(adata_query, ref_model) # Load query into model (creates "surgical" fine-tuned model) query_model = scvi.model.SCVI.load_query_data(adata_query, ref_model) # Surgical training: update only query-specific parameters # weight_decay=0.0: Standard for surgery; prevents reference drift query_model.train(max_epochs=200, plan_kwargs={'weight_decay': 0.0}) # Get latent representation adata_query.obsm['X_scVI'] = query_model.get_latent_representation()
pythonimport scvi import scanpy as sc # Reference with cell type labels adata_ref = sc.read_h5ad('reference_labeled.h5ad') scvi.model.SCVI.setup_anndata(adata_ref, layer='counts', batch_key='batch') ref_vae = scvi.model.SCVI(adata_ref, n_latent=30) ref_vae.train(max_epochs=100) # Convert to scANVI (semi-supervised) scvi.model.SCANVI.setup_anndata(adata_ref, layer='counts', batch_key='batch', labels_key='cell_type', unlabeled_category='Unknown') ref_scanvi = scvi.model.SCANVI.from_scvi_model(ref_vae, labels_key='cell_type', unlabeled_category='Unknown') ref_scanvi.train(max_epochs=50) ref_scanvi.save('reference_scanvi/') # Map query data adata_query = sc.read_h5ad('query.h5ad') adata_query = adata_query[:, adata_ref.var_names].copy() scvi.model.SCANVI.prepare_query_anndata(adata_query, ref_scanvi) query_scanvi = scvi.model.SCANVI.load_query_data(adata_query, ref_scanvi) query_scanvi.train(max_epochs=100, plan_kwargs={'weight_decay': 0.0}) # Transfer labels adata_query.obs['predicted_cell_type'] = query_scanvi.predict() adata_query.obsm['X_scANVI'] = query_scanvi.get_latent_representation()
python# Get prediction probabilities soft_predictions = query_scanvi.predict(soft=True) adata_query.obs['prediction_confidence'] = soft_predictions.max(axis=1) # Flag low-confidence predictions # confidence < 0.5: May be novel cell type or poor mapping low_conf = adata_query.obs['prediction_confidence'] < 0.5 print(f'Low confidence predictions: {low_conf.sum()} ({low_conf.mean():.1%})')
pythonimport scanpy as sc # Combine reference and query for visualization adata_combined = adata_ref.concatenate(adata_query, batch_key='dataset', batch_categories=['reference', 'query']) # Use latent space for neighbors/UMAP sc.pp.neighbors(adata_combined, use_rep='X_scVI') sc.tl.umap(adata_combined) sc.pl.umap(adata_combined, color=['dataset', 'cell_type'], save='_transfer.png')
| Atlas | Model | URL | |-------|-------|-----| | Human Lung Cell Atlas | scANVI | cellxgene.cziscience.com | | Tabula Sapiens | scVI | tabula-sapiens-portal.ds.czbiohub.org | | Mouse Cell Atlas | scVI | bis.zju.edu.cn/MCA |
| Parameter | Surgical | Full Retrain | Notes | |-----------|----------|--------------|-------| | weight_decay | 0.0 | 0.001 | 0.0 preserves reference | | max_epochs | 100-200 | 200-400 | Less for surgery | | early_stopping | True | True | Prevents overfitting |
<!-- AUTHOR_SIGNATURE: 9a7f3c2e-MD-BABU-MIA-2026-MSSM-SECURE -->
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | fail→pass | 3,686 | 3,998 | +8% | 1 | 1 | 0% | 671 | 2,108 | +214% | 0 | 0 | — |
case-04 | pass→pass | 14,480 | 9,183 | -37% | 1 | 1 | 0% | 2,468 | 2,387 | -3% | 0 | 0 | — |
case-20 | pass→pass | 14,578 | 13,215 | -9% | 1 | 1 | 0% | 2,773 | 3,903 | +41% | 0 | 0 | — |
case-21 | pass→pass | 12,065 | 9,486 | -21% | 1 | 1 | 0% | 2,348 | 3,173 | +35% | 0 | 0 | — |
case-22 | pass→pass | 10,332 | 10,699 | +4% | 1 | 1 | 0% | 2,010 | 3,783 | +88% | 0 | 0 | — |
case-01 | pass→pass | 13,309 | 10,492 | -21% | 1 | 1 | 0% | 2,870 | 3,548 | +24% | 0 | 0 | — |
case-02 | fail→pass | 16,087 | 12,985 | -19% | 1 | 1 | 0% | 3,319 | 3,942 | +19% | 0 | 0 | — |
case-03 | fail→pass | 14,576 | 6,313 | -57% | 1 | 1 | 0% | 2,546 | 2,528 | -1% | 0 | 0 | — |
case-06 | fail→pass | 5,244 | 4,045 | -23% | 1 | 1 | 0% | 1,036 | 2,123 | +105% | 0 | 0 | — |
case-07 | fail→pass | 7,056 | 4,300 | -39% | 1 | 1 | 0% | 1,355 | 2,116 | +56% | 0 | 0 | — |
case-08 | fail→pass | 10,071 | 6,033 | -40% | 1 | 1 | 0% | 1,965 | 2,428 | +24% | 0 | 0 | — |
case-09 | fail→pass | 14,591 | 3,974 | -73% | 1 | 1 | 0% | 2,419 | 2,104 | -13% | 0 | 0 | — |
case-10 | pass→fail | 11,740 | 3,068 | -74% | 1 | 1 | 0% | 2,125 | 1,925 | -9% | 0 | 0 | — |
case-11 | pass→pass | 7,501 | 4,018 | -46% | 1 | 1 | 0% | 1,384 | 2,066 | +49% | 0 | 0 | — |
case-12 | pass→pass | 3,146 | 2,434 | -23% | 1 | 1 | 0% | 565 | 1,809 | +220% | 0 | 0 | — |
case-13 | pass→pass | 5,317 | 2,083 | -61% | 1 | 1 | 0% | 998 | 1,726 | +73% | 0 | 0 | — |
case-14 | fail→pass | 7,301 | 3,837 | -47% | 1 | 1 | 0% | 1,472 | 2,084 | +42% | 0 | 0 | — |
case-15 | pass→pass | 3,808 | 1,818 | -52% | 1 | 1 | 0% | 583 | 1,618 | +178% | 0 | 0 | — |
case-16 | fail→pass | 11,847 | 6,339 | -46% | 1 | 1 | 0% | 2,267 | 2,621 | +16% | 0 | 0 | — |
case-17 | pass→pass | 10,318 | 6,194 | -40% | 1 | 1 | 0% | 1,805 | 2,491 | +38% | 0 | 0 | — |
case-18 | pass→pass | 5,908 | 3,316 | -44% | 1 | 1 | 0% | 990 | 1,915 | +93% | 0 | 0 | — |
case-19 | pass→pass | 9,185 | 3,733 | -59% | 1 | 1 | 0% | 1,174 | 1,952 | +66% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +36 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/26/2026 | +41% |
Other measured skills in the registry, with their headline benchmark lift.