# Metabolite Annotation At Scale

> Use when you have extracted a large feature set of m/z values (hundreds to tens of thousands) from a Cardinal MSImagingExperiment object or similar MS dataset and need to assign putative metabolite identities using public structural databases.

- Skill: `holobiomicslab/metabolite-annotation-at-scale-2` (Agent Skill)
- Install (CLI): `npx skillmds@latest add holobiomicslab/metabolite-annotation-at-scale-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/holobiomicslab/metabolite-annotation-at-scale-2/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: CC-BY-4.0
- Author: HolobiomicsLab (https://skillmd.com/u/holobiomicslab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/holobiomicslab/metabolite-annotation-at-scale-2

---


# metabolite-annotation-at-scale

> **License: noncommercial** — confirm your use is a permitted (noncommercial) purpose before applying; commercial use requires a separate license (see `metadata.tool_license`). <!-- asb-license-banner -->
## Summary

Systematic annotation of thousands to hundreds of thousands of mass-to-charge (m/z) values against public metabolite databases (HMDB, Lipidmaps) using tolerance-based matching with user-specified adducts and polarity filters. This skill enables structural identification of metabolites in large MS imaging and LC-MS datasets by matching observed m/z features to database entries within a defined parts-per-million (ppm) error threshold.

## When to use

You have extracted a large feature set of m/z values (hundreds to tens of thousands) from a Cardinal MSImagingExperiment object or similar MS dataset and need to assign putative metabolite identities using public structural databases. Use this skill when you have chosen a specific ppm error tolerance (e.g., 3 ppm for high-resolution instruments, 15 ppm for lower resolution), defined your expected ionization state (M-H, M+H, M+Cl, M+K, etc.), and want to filter and rank candidate annotations by mass accuracy.

## When NOT to use

- Your m/z values are already annotated and you are seeking to refine or validate existing assignments (use RefineLipids or pathway-correlation filters instead).
- You lack prior knowledge of expected adducts or polarity and have not performed exploratory mass-defect or isotope-pattern analysis to constrain the search space.
- Your ppm tolerance is wider than the mass accuracy of your instrument (e.g., requesting ppm_error=15 for Orbitrap data at 5 ppm resolution will yield spuriously high false-positive rates).
- You are working with untargeted LC-MS data with high chemical diversity and have not pre-filtered to a relevant metabolite class or biochemical pathway, risking combinatorial explosion of candidate matches.

## Inputs

- Cardinal MSImagingExperiment object with featureData m/z values
- Extracted m/z feature vector (numeric)
- Metabolite database object (HMDB_db or Lipidmaps_db)
- User-specified parameters: ppm_error (numeric, e.g. 3 or 15), adducts (character vector, e.g. c('M-H', 'M+Cl')), polarity (character, 'negative' or 'positive')

## Outputs

- Annotated data.frame with columns: observed_mz, database_match_name, ppm_error, adduct, (optionally) metabolite_id, inchi_key, molecular_weight
- Summary statistics (row count, mean ppm_error, adduct distribution)
- Seurat object with annotation metadata added to assay or meta.data slot

## How to apply

Extract all m/z features from your MS dataset using featureData() or equivalent accessor; call AnnotateSM() or AnnotateBigData() with your chosen database (HMDB_db or Lipidmaps_db), specifying ppm_error tolerance and a vector of adducts matching your experimental polarity. The function performs bidirectional mass-matching: for each observed m/z, it calculates the theoretical m/z of database metabolites under each specified adduct transformation, then returns all matches within the ppm window ranked by mass error. Inspect the output data.frame for required columns (observed_mz, database_match_name, ppm_error, adduct); optionally filter further using CalculateAnnotationStatistics() to compute annotation quality metrics and apply lipid nomenclature simplification via RefineLipids() if your dataset is lipid-rich. Verify reproducibility by confirming row counts match expected annotation yields and examining the ppm_error distribution.

## Related tools

- **SpaMTP** (R package providing AnnotateSM, AnnotateBigData, CalculateAnnotationStatistics, RefineLipids, and SearchAnnotations functions for metabolite annotation and refinement at scale) — https://github.com/GenomicsMachineLearning/SpaMTP
- **Cardinal** (Provides MSImagingExperiment object structure, featureData() accessor, and foundational spatial MS data handling for m/z feature extraction and annotation workflows) — https://github.com/Vitek-Lab/Cardinal3-vignettes
- **Seurat** (Underlying S4 object framework used by SpaMTP to store and integrate annotated metabolite data with metadata; enables downstream statistical and visualization analyses) — https://satijalab.org/seurat/
- **HMDB Database** (Public metabolite structure database (HMDB_db object) used for mass-matching and metabolite identity lookup in AnnotateSM/AnnotateBigData)
- **Lipidmaps Database** (Public lipid structure database (Lipidmaps_db object) for targeted annotation of lipid-rich samples; complementary to HMDB for MS imaging studies)

## Examples

```
bladder_annotated <- AnnotateSM(bladder, db = Lipidmaps_db, ppm_error = 15, adducts = c('M+H', 'M+K'), polarity = 'positive')
```

## Evaluation signals

- Output data.frame row count matches expected annotation yield (e.g., 67,060 annotated m/z values for HMDB with ppm=3 and M-H/M+Cl adducts on 767,528 features indicates ~8.7% successful annotation rate; compare against internal positive/negative control standards).
- ppm_error distribution is centered near zero with 95% of matches within the user-specified tolerance (e.g., if ppm_error=3, verify that 95%+ of rows have ppm_error ≤ 3); values clustered far from zero suggest mass calibration drift or wrong adduct selection.
- Adduct composition matches experimental expectations (e.g., M-H and M+Cl dominate in negative ESI mode; presence of M+H adducts in negative mode is a red flag indicating annotation failure or polarity mismatch).
- Presence and non-null cardinality of required columns (observed_mz, database_match_name, ppm_error, adduct); absence indicates incomplete function execution.
- Reproducibility check: re-running AnnotateSM/AnnotateBigData with identical parameters on the same input produces identical output data.frame (bit-for-bit) or minor floating-point variance only; row count must be exactly reproducible.

## Limitations

- PPM tolerance must be calibrated to instrument mass accuracy; mismatched thresholds (too loose or too strict) yield high false-positive or false-negative rates respectively, and the article does not provide automated calibration methods.
- Public databases (HMDB, Lipidmaps) have incomplete coverage of known metabolites and may lack recently discovered or uncommon structural variants; annotation absence does not prove absence of the metabolite.
- Ambiguous or isobaric database entries (multiple metabolites with identical or near-identical m/z) are not resolved by mass matching alone; further discrimination requires tandem MS data (MS/MS) or retention time information, for which the article notes 'Pseudo MS/MS-Based Refinement' and 'Refinement with Paired Targeted Metabolic Data' sections are 'To come!'
- Adduct selection must be guided by prior knowledge of ionization conditions (ESI mode, solvent pH, buffer additives); incorrect adduct specification yields zero or spurious matches.
- Scaling to very large m/z feature sets (>1 million) may incur computational overhead; the article does not document runtime or memory complexity for AnnotateBigData.

## Evidence

- [other] How many m/z values from the HMDB database can be annotated using AnnotateBigData with ppm_error=3 and M-H/M+Cl negative adducts?: "How many m/z values from the HMDB database can be annotated using AnnotateBigData with ppm_error=3 and M-H/M+Cl negative adducts?"
- [other] Extract all m/z values from the Cardinal MSImagingExperiment object using featureData(). Call AnnotateBigData with parameters: db=HMDB_db, ppm_error=3, adducts=c('M-H','M+Cl'), polarity='negative'.: "Extract all m/z values from the Cardinal MSImagingExperiment object (767,528 features) using featureData(). 2. Call AnnotateBigData with parameters: db=HMDB_db, ppm_error=3, adducts=c('M-H','M+Cl'),"
- [other] Verify the row count equals the reported 67,060 annotated m/z values and inspect output structure to confirm presence of observed_mz, database_match_name, ppm_error, and adduct columns.: "Return the annotated results data.frame and verify the row count equals the reported 67,060 annotated m/z values. 4. Inspect the output structure to confirm presence of observed_mz,"
- [readme] SpaMTP is an R package designed for the integrative analysis of spatial metabolomics and spatial transcriptomics data with three major functionalities which include m/z metabolite annotation, various downstream statistical analysis including differential metabolite expression and pathway analysis, and integrative spatial-omics analysis.: "SpaMTP is an R package designed for the integrative analysis of spatial metabolomics and spatial transcriptomics data. SpaMTP inherits functionalities from two well established R packages (Cardinal"
- [other] Runs lipid nomenclature simplification on annotations; RefineLipids can be used to simplify the lipid nomenclature into common lipid categories and classes.: "RefineLipids can be used to simplify the lipid nomenclature into common lipid categories and classes"
- [other] AnnotateSM(bladder, db = Lipidmaps_db, ppm_error = 15 with M+K adduct specified): "AnnotateSM(bladder, db = Lipidmaps_db, ppm_error = 15"
- [other] Pseudo MS/MS-Based Refinement and Refinement with Paired Targeted Metabolic Data sections marked as 'To come!' indicating incomplete development of advanced refinement strategies.: "## 3) Pseudo MS/MS-Based Refinement

To come!"

