metabolomics/targeted-analysis/SKILL.md
Designs and validates quantitative targeted metabolomics assays (MRM/SRM on triple-quadrupole, PRM on high-resolution instruments) to report absolute concentrations. Covers the internal-standard strategy (external cal -> global IS -> standard addition -> stable-isotope-labeled IS), weighted calibration judged by back-calculated %RE not R-squared, ion-ratio quantifier/qualifier confirmation, matrix-effect/recovery characterization, and ICH M10 method validation. Use when quantifying a closed panel of known metabolites with units, building or validating an LC-MS/MS assay, choosing an IS or calibration weighting, or judging whether a reported concentration is trustworthy. For untargeted feature detection see metabolomics/xcms-preprocessing; for group statistics see metabolomics/statistical-analysis; for flux/MID/tracing see metabolomics/isotope-tracing.
npx skillsauth add GPTomics/bioSkills bio-metabolomics-targeted-analysisInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Reference examples tested with: R 4.3+, ggplot2 3.5+, Skyline 23.1+, pandas 2.2+, numpy 1.26+
Before using code patterns, verify installed versions match. If versions differ:
packageVersion('<pkg>') then ?function_name to verify parameterspip show <package> then help(module.function) to check signatures<tool> --version then <tool> --help to confirm flagsAn absolute concentration requires three inputs the code cannot supply: an authentic reference standard (its certificate-of-analysis purity scales every reported number), a stable-isotope-labeled internal standard that co-elutes with the analyte, and a per-analyte validation record. Without these, the workflow below produces relative peak-area ratios dressed as concentrations.
If code throws ImportError, AttributeError, or TypeError, introspect the installed package and adapt the example to match the actual API rather than retrying.
"Quantify these specific metabolites and give me concentrations with units" -> Fit weighted calibration curves on authentic standards, normalize each analyte to a co-eluting stable-isotope-labeled internal standard, confirm identity by ion ratio, and report concentrations only within the validated range.
Ion suppression is competition for charge and droplet surface in the electrospray source: a co-eluting matrix component (phospholipids late in a reversed-phase gradient, salts at the void) steals ionization from the analyte. Suppression is a property of the co-elution, not of the analyte, so it is retention-time-dependent and lot-dependent. The only mechanism that truly removes it is a stable-isotope-labeled internal standard (SIL-IS) that sits in the identical droplet at the identical instant: the suppression cancels in the analyte/IS area ratio. An IS that elutes even half a minute away samples a different point on the suppression landscape and injects new error rather than removing it. Every other safeguard in this skill -- weighting, ion ratios, validation -- assumes this cancellation is working; the gap between a solvent calibration curve and a matrix-matched curve is a direct readout of how badly the IS is failing.
| Axis | Untargeted (discovery) | Targeted (quantification) | |---|---|---| | Analyte set | Open -- everything ionizable | Closed -- a panel defined before acquisition | | Output | Relative fold-change; often putative IDs | Absolute concentration for confirmed analytes | | Instrument | High-res full-scan / DDA (Orbitrap, QTOF) | Triple-quad SRM/MRM, or high-res PRM | | Validation | QA/QC framework (Broadhurst, mQACC) | Full bioanalytical validation possible (ICH M10) | | Question | "What changed?" | "How much is there?" |
Targeted buys sensitivity and absolute quant by spending scope (only what is on the list is seen) and up-front method development. Common pattern: untargeted discovery -> targeted validation of the hits. Feature detection upstream is metabolomics/xcms-preprocessing; this skill begins once the panel and transitions are defined.
A transition is a precursor-m/z -> product-m/z pair plus a tuned collision energy. On a triple quadrupole, Q1 isolates the precursor, the collision cell fragments it, Q3 isolates one product: the double mass filter is the source of MRM sensitivity. SRM monitors one transition; MRM multiplexes many. Each analyte should carry at least two transitions -- a quantifier (most intense/cleanest, used for concentration) and one or more qualifiers (orthogonal confirmation). PRM replaces Q3 with a high-resolution analyzer that records the full product spectrum in parallel, so transitions are chosen post hoc and isobaric interferences are resolved by exact mass; MRM still wins on absolute sensitivity and very large panels. Dwell time is the signal-accumulation time per transition; cycle time must stay short enough for at least 10-15 points across each chromatographic peak (convention). Scheduled MRM monitors each transition only within a retention-time window so a large panel keeps adequate dwell -- but a peak that drifts out of its window vanishes with no error message, the classic scheduled-MRM failure.
| Goal / situation | Internal standard | Calibration | Validation depth | Why | |---|---|---|---|---| | Clinical / regulated / PK number | One SIL-IS per analyte (13C/15N) | Multi-level weighted curve, judged by %RE | Full ICH M10 (accuracy, precision, MF, recovery, carryover, stability, ISR) | A number driving a decision must carry its evidence | | Cross-study quantitative claim | SIL-IS per analyte or per RT/chemical cluster | Multi-level weighted | Accuracy/precision + matrix-factor on QCs | Comparability across runs demands characterized bias | | Exploratory research, ranking | Few global IS, or per-class | 1/x^2 weighted, low-end %RE checked | Broadhurst/mQACC QC discipline (pooled QC, blanks, RSD filtering) | Relative comparison tolerates residual matrix bias | | Dirty matrix, isobaric interferences | SIL-IS + high-res | PRM, post-hoc transitions | Selectivity dominated | Exact-mass product resolves co-eluters a unit-resolution Q3 cannot | | Large standardized panel (600+) | Kit-supplied class IS | Single/limited-point (vendor) | Vendor + bridging study before pooling sites | Kit buys comparability and throughput, not per-analyte full-validation accuracy | | Carbon source / pathway rate | (tracer, not IS) | -- | -- | Flux question: hand off to metabolomics/isotope-tracing; MID measures rate, not pool size |
The IS rule of thumb: ask how far (in retention time and chemistry) each analyte is from its assigned IS -- that distance is the size of the uncorrected matrix error. 13C/15N at non-exchangeable positions are preferred over deuterium: deuterium causes a small reversed-phase retention shift (the deuterium isotope effect) that can chromatographically separate the IS from its analyte so it stops correcting suppression, and labile deuteriums back-exchange to H. If forced to a deuterated IS, verify co-elution by overlaying analyte and IS chromatograms.
| Weighting | When | Effect | |---|---|---| | Unweighted (OLS) | Narrow range, near-constant variance | High points dominate; low-end bias on heteroscedastic MS data -- usually wrong | | 1/x | Moderate range (1-2 orders) | Down-weights high concentrations; restores low-end fit | | 1/x^2 | Wide range (3+ orders), the common LC-MS default | Aggressively down-weights the top; can over-weight the low end -- still compare, do not reflex | | Quadratic | Genuine, mechanism-explained curvature (detector saturation) | Never to paper over a bad linear fit |
MS detector response is heteroscedastic -- absolute variance grows with concentration -- so weighting models the variance structure (1/x and 1/x^2 are parametric stand-ins for 1/variance). Select empirically: fit candidate weightings, then pick the one minimizing the sum of absolute back-calculated relative error (%RE) across levels, especially the bottom two or three. R-squared is the wrong instrument: it is dominated by high-leverage top points, so a curve with R-squared 0.999 can be +40% biased at the LLOQ. Use a fitted (non-zero) intercept; forcing the line through the origin re-introduces low-end bias. The blank (matrix only) and zero (matrix + IS) are diagnostic, not calibration points.
Goal: Fit a calibration curve on the analyte/IS response ratio and accept it by per-level back-calculation accuracy, not by R-squared.
Approach: Fit 1/x^2-weighted linear regression of response ratio on nominal concentration, back-calculate every standard, flag any non-LLOQ level outside +/-15% and the LLOQ outside +/-20%, and set the LLOQ to the lowest passing level.
standards <- data.frame(
conc = c(1, 5, 10, 25, 50, 100, 250, 500, 1000),
analyte_area = c(480, 2500, 4900, 12100, 24500, 49000, 121000, 245000, 488000),
istd_area = c(100000, 98000, 99000, 101000, 100000, 98000, 101000, 99000, 100000)
)
standards$ratio <- standards$analyte_area / standards$istd_area
fit <- lm(ratio ~ conc, data = standards, weights = 1 / standards$conc^2)
standards$back_calc <- (standards$ratio - coef(fit)[1]) / coef(fit)[2]
standards$re_pct <- (standards$back_calc - standards$conc) / standards$conc * 100
# ICH M10: each calibrator within +-15%, +-20% at the LLOQ (lowest level)
tol <- ifelse(standards$conc == min(standards$conc), 20, 15)
standards$pass <- abs(standards$re_pct) <= tol
lloq <- min(standards$conc[standards$pass])
Goal: Convert raw analyte area to a matrix-corrected response that the calibration curve maps to concentration.
Approach: Divide analyte area by co-eluting SIL-IS area per sample, then invert the same response-ratio calibration; matrix effect and extraction recovery cancel in the ratio.
samples$ratio <- samples$analyte_area / samples$istd_area
samples$conc <- (samples$ratio - coef(fit)[1]) / coef(fit)[2]
samples$conc[samples$conc < lloq] <- NA # below validated range -> not reportable
Goal: Guard against quantifying an isobaric co-eluter as the analyte.
Approach: Compute the qualifier/quantifier area ratio per sample, compare to the mean calibrator ratio, and flag samples outside the tolerance window -- a drifted ratio means the quantifier peak is partly something else.
cal_ratio <- mean(standards$qualifier_area / standards$quantifier_area)
samples$ion_ratio <- samples$qualifier_area / samples$quantifier_area
# SANTE/2020/12830 uses +-30% relative for LC-MS/MS qualifier/quantifier ratios
samples$id_confirmed <- abs(samples$ion_ratio - cal_ratio) / cal_ratio <= 0.30
MRM gives mass selectivity, not identity: two compounds can share a precursor->product transition (many acylcarnitines share m/z 85; lipids share head-group fragments). Identity needs retention time plus the ion ratio plus an authentic standard. Near the LLOQ the qualifier may fall below its own detection limit, so ion-ratio confirmation is usually only enforceable above a few times the LLOQ -- state that limit rather than hiding it. A single-transition method has no defense against isobaric interference and is a documented compromise, not a default.
Goal: Set the lowest reliably quantifiable concentration from noise and accuracy, not from an extrapolated curve.
Approach: Estimate LOD from blank-signal scatter (S/N ~3) and confirm the LLOQ as the lowest calibrator meeting the +/-20% back-calculation and precision criteria; never anchor the curve below the real noise floor to claim sensitivity.
blank_areas <- c(100, 120, 95, 110, 105)
slope <- coef(fit)[2]
lod <- (mean(blank_areas) + 3 * sd(blank_areas)) / slope # S/N~3 convention
# LLOQ is the lowest calibrator passing +-20% %RE AND precision -- not 10*SD/slope alone
| Threshold | Source | Rationale | |---|---|---| | Calibrator back-calc within +/-15% (+/-20% at LLOQ), >=75% of >=6 levels pass | ICH M10 (Step 4, 2022) | Per-level accuracy, not correlation, defines a usable curve | | QC accuracy +/-15% (+/-20% at LLOQ); precision CV <=15% (<=20% at LLOQ) | ICH M10 | Intra- and inter-day acceptance at >=4 levels | | IS-normalized matrix factor CV <=15% across >=6 lots | ICH M10 / Matuszewski 2003 | Proof the IS cancels matrix effect; raw MF may be poor while IS-normalized MF ~1 | | Carryover <=20% of LLOQ (analyte), <=5% (IS) | ICH M10 | Measured in a blank after the ULOQ; concentration-dependent, must be quantified not eyeballed | | Selectivity: interference at LLOQ <=20% of analyte, <=5% of IS response | ICH M10 | Across >=6 individual matrix lots | | ISR: >=2/3 of reanalyzed study samples within +/-20% | ICH M10 | Only test that catches incurred-sample-specific problems spiked QCs cannot | | Ion-ratio tolerance +/-30% relative (LC-MS/MS) | SANTE/2020/12830 | Illustrative codified window; enforce only above a few times the LLOQ | | >=10-15 points across a chromatographic peak | Convention | Reliable integration; sets the cycle-time ceiling | | S/N ~3 = LOD, ~5-10 = LLOQ | Convention | Detection vs reliable quantification; LLOQ also bounded by accuracy/precision |
| Error / symptom | Cause | Solution | |---|---|---| | Curve accepted on R-squared, biased at LLOQ | Unweighted heteroscedastic fit | Weight (1/x, 1/x^2); accept by per-level back-calculated %RE | | Deuterated IS gives lot-dependent ratios | Deuterium isotope effect separates IS from analyte; lost matrix correction | Use 13C/15N at non-exchangeable positions, or verify co-elution explicitly | | High-end curvature mis-read as detector saturation | Analyte natural isotopes bleed into a too-close IS channel | Widen IS-analyte mass gap to >=3-4 Da; use nonlinear isotopic-crosstalk correction | | Beautiful CVs, wrong group means | One global IS across diverse analytes -- precision/accuracy decoupled | SIL-IS per analyte or per RT/chemical cluster | | Low samples after a high sample read high | Concentration-dependent carryover | Inject a blank after the ULOQ, randomize run order, report measured carryover | | Skyline never ratios analyte to IS | IS not tagged Label Type = heavy and paired to its light analyte | Set Label Type heavy in the transition list; pair by molecule name | | Validated assay, study numbers still wrong | Pre-analytical degradation (no error message) | Quench fast, measure stability, monitor adenylate energy charge |
development
Installs 425 bioinformatics skills covering sequence analysis, RNA-seq, single-cell, variant calling, metagenomics, structural biology, and 56 more categories. Use when setting up bioinformatics capabilities or when a bioinformatics task requires specialized skills not yet installed.
testing
Chains a somatic (tumor-normal) SNV/indel and structural-variant pipeline end to end with GATK Mutect2 (or Strelka2), wiring the somatic-specific machinery - panel-of-normals and gnomAD germline-resource priors, GetPileupSummaries/CalculateContamination, and LearnReadOrientationModel FFPE/oxoG orientation-bias filtering fed into FilterMutectCalls. Use when calling somatic mutations from a tumor-normal pair (or tumor-only with PoN caveats), deciding which artifact filter removes which class of false positive, reasoning about VAF/purity/ploidy and clonal-vs-subclonal detection, adding somatic SV/CNV or TMB/MSI/signatures, or routing variants to AMP/ASCO/CAP tier and oncogenicity interpretation (never germline ACMG).
development
End-to-end pooled and single-cell CRISPR screen analysis from FASTQ to hit genes. Orchestrates library design QC, guide counting, six-stage screen QC (plasmid Gini, replicate Pearson, CEGv2 PR-AUC, copy-number artifact), method-appropriate hit calling across MAGeCK RRA/MLE, BAGEL2, drugZ, JACKS, and Chronos, cancer-cell-line copy-number correction (CRISPRcleanR / Chronos), batch correction for multi-batch screens, and the specialized branches for combinatorial paralog screens, single-cell Perturb-seq, base-editor variant-function screens, prime-editor screens, and in vivo bottleneck-aware screens. Use when analyzing any pooled CRISPR screen end-to-end, matching the hit-calling method to the experimental design, integrating copy-number correction into the pipeline, or branching the workflow for single-cell, combinatorial, base-editor, prime-editor, or in vivo variants.
development
Transcribe DNA to RNA and translate to protein using Biopython, with NCBI codon-table selection, CDS validation, and six-frame ORF finding. Use when converting a CDS or ORF to its amino-acid sequence, selecting a non-standard (mitochondrial, bacterial, ciliate) genetic code, validating a coding sequence, or scanning all reading frames.